<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>3_react生命周期(新)</title>
</head>
<body>
  <!-- 准备好一个“容器” -->
  <div id="test"></div>

  <!-- 引入react核心库 -->
  <script type="text/javascript" src="../js/17.0.2/react.development.js"></script>
  <!-- 引入react-dom，用于支持react操作DOM -->
  <script type="text/javascript" src="../js/17.0.2/react-dom.development.js"></script>
  <!-- 引入babel，用于将jsx转为js -->
  <script type="text/javascript" src="../js/17.0.2/babel.min.js"></script>

  <!-- 此处一定要写babel -->
  <script type="text/babel">
    // 1. 创建组件
    class Count extends React.Component {
     //  构造器
     constructor(props) {
       console.log('Count-constructor')
       super(props)
       //  初始化状态
       this.state = {count: 0}
     }

     // 加1按钮的回调
     add = () => {
       // 获取原状态
       const {count} = this.state
       // 更新状态
       this.setState({count: count+1})
     }
     // 卸载组件按钮的回调
     death = () => {
       ReactDOM.unmountComponentAtNode(document.getElementById('test'))
     }
     // 强制更新按钮的回调
     force = () => { 
       this.forceUpdate()
     }

     // 派生  state 的值在任何时候都取决于 props，那么可以使用
     static getDerivedStateFromProps(props, state) {
       console.log('getDerivedStateFromProps', props, state)
       return null
     }

     // 组件将要挂载的钩子
     // UNSAFE_componentWillMount() {
     //   console.log('Count-componentWillMount')
     // }
     // 组件挂载完毕的钩子
     componentDidMount() {
       console.log('Count-componentDidMount')
     }
     // 组件将要卸载
     componentWillUnmount() {
       console.log('Count-componentWillUnmount')
     }

     // 控制组件更新的“阀门”
     shouldComponentUpdate() {
       console.log('Count-shouldComponentUpdate')
       return true
     }

     getSnapshotBeforeUpdate(prevprops, prevstate) {
       console.log('getSnapshotBeforeUpdate', prevprops, prevstate)
       return null
     }

     // 组件将要更新的钩子
     // UNSAFE_componentWillUpdate() {
     //   console.log('Count-componentWillUpdate')
     // }
     // 组件更新完毕的钩子
     componentDidUpdate(prevprops, prevstate, snapshotValue) {
       console.log('Count-componentDidUpdate', prevprops, prevstate, snapshotValue)
     }

     render() {
       console.log('Count-render')
       const {count} = this.state
       return (
         <div>
           <h2>当前求和为：{count}</h2>
           <button onClick={this.add}>点我+1</button>  
           <button onClick={this.death}>卸载组件</button>  
           <button onClick={this.force}>不更改任何状态中的数据，强制更新一下</button>  
         </div>
       )
     }
    }
    // 父组件A   
    class A extends React.Component {
      state = {carName: '奔驰🐑'}
      changeCar = () => {
        this.setState({carName: '奥拓🐘'})
      }
      render() {
       console.log('A-render')
        return (
          <div>
           <div>A</div>
           <button onClick={this.changeCar}>换车</button>
           <B carName={this.state.carName}/>
          </div>
        )
      }
    }
    // 子组件B
    class B extends React.Component {
     // 组件将要接收新的props的钩子
     // UNSEFT_componentWillReceiveProps(props) {
     //   console.log('B-componentWillReceiveProps', props)
     // }
     shouldComponentUpdate() {
       console.log('B-shouldComponentUpdate')
       return true
     }
     // UNSAFE_componentWillUpdate() {
     //   console.log('B-componentWillUpdate')
     // }
     componentDidUpdate() {
       console.log('B-componentDidUpdate')
     }
      render() {
        console.log('B-render')
        return (
          <div>B {this.props.carName}</div>
        )
      }
    }
    
    // 2. 渲染组件到页面
    ReactDOM.render(<Count count={9} />, document.getElementById('test'))
  </script>
</body>
</html>